package com.woniu.mealsService.service.impl;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.dto.StoreAppliesDto;
import com.woniu.dto.StoreApplyFileDto;
import com.woniu.exception.meals.CommentException;
import com.woniu.exception.meals.StoreException;
import com.woniu.mealsService.model.Product;
import com.woniu.mealsService.model.Store;
import com.woniu.mealsService.mapper.StoreMapper;
import com.woniu.mealsService.model.StoreProduct;
import com.woniu.mealsService.service.CommentService;
import com.woniu.mealsService.service.ProductService;
import com.woniu.mealsService.service.StoreProductService;
import com.woniu.mealsService.service.StoreService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.param.InsertStoreParam;
import com.woniu.param.ModifyStoreParam;
import com.woniu.param.StoreOpenTimeParam;
import com.woniu.server.RedisKey;
import com.woniu.server.RedisUtil;
import com.woniu.utils.AliyunOSSUtil;
import com.woniu.utils.EnumException;
import com.woniu.utils.OSSUtil;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 店铺表 服务实现类
 * </p>
 *
 * @author jiang
 * @since 2024年12月09日
 *
 */
@Service
public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements StoreService {

    @Resource
    ProductService productService;
    @Resource
    StoreProductService storeProductService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void selectOpenTimeByStoreId(StoreOpenTimeParam storeOpenTimeParam) throws StoreException {

        if (storeOpenTimeParam.getStoreEndTime().compareTo(storeOpenTimeParam.getStoreStartTime()) < 0)
            throw new StoreException("结束营业时间不能早于开始营业时间", 10016);
        Store store = this.getById(storeOpenTimeParam.getStoreId());
        store.setUpdateTime(LocalDateTime.now());
        store.setStoreEndTime(storeOpenTimeParam.getStoreEndTime());
        store.setStoreStartTime(storeOpenTimeParam.getStoreStartTime());
        this.updateById(store);
    }

    @Override
    public void updateAfficheByStoreId(Integer storeId, String newAffiche) {
        Store store = this.getById(storeId);
        store.setAffiche(newAffiche);
        this.updateById(store);
    }

    @Override
    public void insertStore(InsertStoreParam insertStoreParam) throws Exception {
//        // 处理文件上传
//        String imageURLLicense = null;
//        String imageURLPermit = null;
//        if (insertStoreParam.getLicense() != null && insertStoreParam.getPermit() != null) {
//            // 判断文件格式
//            String type = FileTypeUtil.getType(insertStoreParam.getLicense().getInputStream());
//            String type1 = FileTypeUtil.getType(insertStoreParam.getPermit().getInputStream());
//            if (!type.equals("jpg") && !type.equals("png") && !type.equals("pdf") && !type1.equals("jpg") && !type1.equals("png") && !type1.equals("pdf")) {
//                throw new StoreException("文件格式错误", 10010);
//            }
//
//            // 给文件改名UUID
//            String filename = insertStoreParam.getLicense().getOriginalFilename();
//            String filename1 = insertStoreParam.getPermit().getOriginalFilename();
//            String substring = filename.substring(filename.lastIndexOf("."));
//            String substring1 = filename1.substring(filename1.lastIndexOf("."));
//            String realFilename = UUID.randomUUID().toString() + substring;
//            String realFilename1 = UUID.randomUUID().toString() + substring1;
//
//            // 上传文件
//            imageURLLicense = OSSUtil.uploadFile(insertStoreParam.getLicense().getInputStream(), realFilename, "woniu108lanyu");
//            imageURLPermit = OSSUtil.uploadFile(insertStoreParam.getPermit().getInputStream(), realFilename1, "woniu108lanyu");
//        } else {
//            throw new StoreException("营业执照和餐饮许可证需上传", 10011);
//        }
        String applyForStore = null;
        long ttl = 0;
        try {
            applyForStore = redisUtil.hget(RedisKey.applyList(), RedisKey.applyForStore(String.valueOf(insertStoreParam.getUserId())));
            redisUtil.removeHash(RedisKey.applyList(),RedisKey.applyForStore(String.valueOf(insertStoreParam.getUserId())));
            redisUtil.del(RedisKey.applyForStore(String.valueOf(insertStoreParam.getUserId())));
            ttl = redisUtil.getExpire(RedisKey.applyForStore(String.valueOf(insertStoreParam.getUserId())));
            Store store = new Store();
            store.setStoreEndTime(insertStoreParam.getStoreEndTime());
            store.setStoreStartTime(insertStoreParam.getStoreStartTime());
            store.setUpdateTime(LocalDateTime.now());
            store.setCreateTime(LocalDateTime.now());
            store.setLicense(insertStoreParam.getLicense());
            store.setPermit(insertStoreParam.getPermit());
            store.setStoreIntro(insertStoreParam.getStoreIntro());
            store.setUserId(insertStoreParam.getUserId());
            store.setUserName(insertStoreParam.getUserName());
            store.setPhone(insertStoreParam.getPhone());
            store.setStoreName(insertStoreParam.getStoreName());
            store.setStatus(1);
            store.setStoreStatus(1);
            store.setDeleteFlag(0);
            this.save(store);
        }catch (Exception e){
            redisUtil.saveHash(RedisKey.applyList(),RedisKey.applyForStore(String.valueOf(insertStoreParam.getUserId())),applyForStore);
            redisUtil.set(RedisKey.applyForStore(String.valueOf(insertStoreParam.getUserId())),"1",ttl);
            throw new RuntimeException("新增店铺失败");
        }
    }

    @Override
    public void modifyTheBasicInformationOfTheStore(ModifyStoreParam modifyStoreParam) throws StoreException, IOException {
        Store store = this.getOne(new QueryWrapper<Store>().eq("user_id", modifyStoreParam.getUserId()));
        String imageURLLicense = null;
        String imageURLPermit = null;
        if (modifyStoreParam.getLicense() != null) {
            // 判断文件格式
            String type = FileTypeUtil.getType(modifyStoreParam.getLicense().getInputStream());
            if (!type.equals("jpg") && !type.equals("png") && !type.equals("pdf")) {
                throw new StoreException("文件格式错误", 10010);
            }

            // 给文件改名UUID
            String filename = modifyStoreParam.getLicense().getOriginalFilename();
            String substring = filename.substring(filename.lastIndexOf("."));
            String realFilename = UUID.randomUUID().toString() + substring;

            // 上传文件
            imageURLLicense = OSSUtil.uploadFile(modifyStoreParam.getLicense().getInputStream(), realFilename, "woniu108lanyu");
            store.setLicense(imageURLLicense);
        }
        if (modifyStoreParam.getPermit() != null) {
            // 判断文件格式
            String type = FileTypeUtil.getType(modifyStoreParam.getPermit().getInputStream());
            if (!type.equals("jpg") && !type.equals("png") && !type.equals("pdf")) {
                throw new StoreException("文件格式错误", 10010);
            }
            // 给文件改名UUID
            String filename = modifyStoreParam.getPermit().getOriginalFilename();
            String substring = filename.substring(filename.lastIndexOf("."));
            String realFilename = UUID.randomUUID().toString() + substring;
            // 上传文件
            imageURLPermit = OSSUtil.uploadFile(modifyStoreParam.getPermit().getInputStream(), realFilename, "woniu108lanyu");
            store.setPermit(imageURLPermit);
        }
        store.setStoreName(modifyStoreParam.getStoreName());
        store.setPhone(modifyStoreParam.getPhone());
        store.setStoreIntro(modifyStoreParam.getStoreIntro());
        store.setUpdateTime(LocalDateTime.now());
        this.updateById(store);

    }


    //    从该系统上下架该商户(修改对应店铺状态为下架),同时下架该店铺的所有菜品信息
    @Override
    public void disStoreByStoreId(Integer storeId) {
        Store store = this.getById(storeId);
        store.setStoreStatus(0);
        store.setDeleteFlag(1);
        this.updateById(store);
        List<Product> products = productService.list(new QueryWrapper<Product>().eq("store_id", storeId));
        List<StoreProduct> storeProducts = storeProductService.list(new QueryWrapper<StoreProduct>().eq("store_id", storeId));
        for (Product product : products) {
            product.setProductDel(1);
            productService.updateById(product);
        }
        for (StoreProduct storeProduct : storeProducts) {
            storeProduct.setStoreProductState(1);
            storeProduct.setChangeUser(this.getById(storeId).getUserName());
            storeProductService.updateById(storeProduct);
        }

    }

    /**
     * 选择所有商店
     * 此方法通过调用StoreMapper中的selectAllStore方法来获取数据库中所有的商店信息
     * 它没有输入参数，返回一个Store对象的列表
     * @return 包含所有商店信息的列表
     */
    @Override
    public List<Store> selectAllStore() {
        List<Store> stores = storeMapper.selectAllStore();
        return stores;
    }

    @Override
    public StoreApplyFileDto upLoad(MultipartFile license, MultipartFile permit) throws Exception {
        StoreApplyFileDto storeApplyFileDto = null;
        if (license != null && permit != null) {
            storeApplyFileDto= new StoreApplyFileDto();
            InputStream inputStream = license.getInputStream();
            byte[] bytes = new byte[inputStream.available()];
            license.getInputStream().read(bytes);
            if (!AliyunOSSUtil.isJpg(bytes) && !AliyunOSSUtil.isPng(bytes)){
                throw new CommentException(EnumException.COMMENTUPLOADIMG_TYPE_EXCEPTION);
            }
            String suffix = StringUtils.getFilenameExtension(license.getOriginalFilename());
            String prefix = UUID.randomUUID().toString().replaceAll("-", "");
            String newFilename = prefix + "." + suffix;
            String licenseStr = aliyunOSSUtil.uploadFile(license.getInputStream(), newFilename, "jiang115");
            storeApplyFileDto.setLicense(licenseStr);
            InputStream inputStream1 = permit.getInputStream();
            byte[] bytes1 = new byte[inputStream1.available()];
            permit.getInputStream().read(bytes1);
            if (!AliyunOSSUtil.isJpg(bytes1) && !AliyunOSSUtil.isPng(bytes1)){
                throw new CommentException(EnumException.COMMENTUPLOADIMG_TYPE_EXCEPTION);
            }
            String filenameExtension = StringUtils.getFilenameExtension(permit.getOriginalFilename());
            String s = UUID.randomUUID().toString().replaceAll("-", "");
            String per = s + "." + filenameExtension;
            String perStr = aliyunOSSUtil.uploadFile(permit.getInputStream(), per, "jiang115");
            storeApplyFileDto.setPermit(perStr);
            return storeApplyFileDto;
        }
        return null;
    }

    @Override
    @XxlJob("removeStoreAppliesTime")
    public List<StoreAppliesDto> removeStoreAppliesTime() throws Exception {
        Map<Object, Object> objectObjectMap = redisUtil.hgetAll(RedisKey.applyList());
        objectObjectMap.entrySet().stream().forEach(o->{
            if (o.getValue()!=null){
                StoreAppliesDto bean = JSONUtil.toBean(o.getValue().toString(), StoreAppliesDto.class);
                long expire = redisUtil.getExpire(RedisKey.applyForStore(String.valueOf(bean.getUserId())));
                if (expire<=300){
                    redisUtil.saveHash(RedisKey.applyTimeOutList(),RedisKey.applyTimeOut(String.valueOf(bean.getUserId())),JSONUtil.toJsonStr(bean));
                }
                redisUtil.removeHash(RedisKey.applyList(),RedisKey.applyForStore(String.valueOf(bean.getUserId())));
            }
        });
        List<StoreAppliesDto> applyForStore = new ArrayList<>();
        Map<Object, Object> timeOutList = redisUtil.hgetAll(RedisKey.applyTimeOutList());
        timeOutList.entrySet().stream().forEach(o->{
            if (o.getValue()!=null){
                StoreAppliesDto bean = JSONUtil.toBean(o.getValue().toString(), StoreAppliesDto.class);
                applyForStore.add(bean);
            }
        });
        return applyForStore;
    }


    @Override
    public String updateHandOrder(Integer status,String userId) throws Exception {
        Store store = this.getOne(new LambdaQueryWrapper<Store>().eq(Store::getUserId, userId));
        if (null == store){
            throw new StoreException(EnumException.STORE_NULL_EXCEPTION);
        }
        store.setStatus(status);
        this.updateById(store);
        return "更新接单方式成功";
    }
    @XxlJob("test")
    public void test() throws Exception{
        System.out.println("测试");
    }
}
